import { login, logout, getInfo } from "@/api/user";
import { getToken, setToken, removeToken } from "@/utils/auth";
// 引入路由表
import { constantRoutes, allAsyncRoutes, anyRoute } from "@/router/routes";
import router from "@/router";
import {cloneDeep} from 'lodash'


// 封装递归过滤异步路由  返回符合用户菜单的路由表
function filterAsyncRoutes(allAsyncRoutes, routeNames) {
  return allAsyncRoutes.filter((route) => {
    // 如果route的name 不在routeNames里面  直接过滤掉
    if (!routeNames.includes(route.name)) return false;

    // 如果当前route还有子路由 那么需要对子路由过滤  用递归
    if (route.children && route.children.length > 0) {
      route.children = filterAsyncRoutes(route.children, routeNames);
    }
    return true;
  });
}

const getDefaultState = () => {
  return {
    token: getToken(), // 默认token
    name: '',
    avatar: '',
    // 以下是实现权限管理 用到的 state
    roles:[] , // 角色名称路由的数组
    buttons: [] , // 按钮权限的数组
    routes:[], // 用于显示导航菜单的路由数组,包括了constantRoutes和asyncRoutes
  };
};

const state = getDefaultState();

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState());
  },
  // 设置token
  SET_TOKEN(state, newToken) {
    state.token = newToken;
    setToken(newToken);
  },
  // 删除token
  REMOVE_TOKEN(state) {
    state.token = "";

    removeToken();
  },
  // 设置用户信息
  SET_USER(state, value) {
    state.name = value.name
    state.avatar = value.avatar // 头像
    state.roles = value.roles // 角色列表
    state.buttons = value.buttons // 按钮权限列表
  },
  // 保存异步路由
  SET_ROUTES (state,asyncRoutes) {
    // 将当前用户的异步权限路由和备选路由 添加到路由器
    router.addRoutes([...asyncRoutes,anyRoute])
    // 保存异步路由   合并数组
    state.routes = constantRoutes.concat(asyncRoutes)
  },
  
};

const actions = {
  // 登录
  async loginActions({ commit }, value) {
    try {
      const res = await login(value);
      commit("SET_TOKEN", res.data.token);
      return res;
    } catch (e) {
      return Promise.reject(e);
    }
  },

  // 请求用户信息
  async userInfoActions({ commit }) {
    try {
      const res = await getInfo();
      commit("SET_USER", res.data);

      // 处理异步路由
      const asyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes), res.data.routes)
      commit('SET_ROUTES', asyncRoutes)
      
    } catch (e) {
      return Promise.reject(e);
    }
  },

  // 退出登录
  async logoutActions({ commit }) {
    try {
      await logout();
      commit("REMOVE_TOKEN");
      commit("SET_USER",{
          name : '',
          avatar : '', 
          roles : [] ,
          buttons : [], 
      });
    } catch (e) {
      return Promise.reject(e);
    }
  },

  // 重置token
  resetToken({ commit }) {
    return new Promise((resolve) => {
      commit("REMOVE_TOKEN");
      resolve();
    });
  },
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
